package com.sxz.mall.mallauthserver.controller;

import com.alibaba.fastjson.JSON;
import com.sxz.mall.common.constant.AuthConstant;
import com.sxz.mall.common.constant.SMSConstant;
import com.sxz.mall.common.exception.BizCodeEnum;
import com.sxz.mall.common.utils.R;
import com.sxz.mall.mallauthserver.feign.MemberFeignService;
import com.sxz.mall.mallauthserver.vo.LoginVO;
import com.sxz.mall.mallauthserver.vo.MemberVO;
import com.sxz.mall.mallauthserver.vo.UserRegisterVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class LoginController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private MemberFeignService memberFeignService;

    // 很多服务都会校验登录与否，所以横切处理，添加配置类

//    @GetMapping("/login.html")
//    public String login() {
//        return "login";
//    }
//
//    @GetMapping("/reg.html")
//    public String reg() {
//        return "reg";
//    }

    @ResponseBody
    @GetMapping("/sms/sendCode")
    public R sendCode(String phone) {

        // 60秒存储一次，前端可能刷新页面，频繁发短信
        // 1、获取
        String code = stringRedisTemplate.opsForValue().get(SMSConstant.SMS_CODE_PERFIX + phone);
        if (code != null && StringUtils.isEmpty(code.toString())) {
            String lastTime = code.toString().split("_")[1];
            long l = System.currentTimeMillis() - Long.parseLong(lastTime);
            if (l <= 60000) {
                System.out.println("60秒内，不发送短信");
                return R.error(BizCodeEnum.VALID_SMS_EXCEPTION.getCode(), BizCodeEnum.VALID_SMS_EXCEPTION.getMsg());
            }
        }


        String rcode = UUID.randomUUID().toString().substring(0, 5);
        System.out.println("要给哪个手机发送验证码" + phone + "验证码是：" + rcode);

        String newCode = rcode + "_" + System.currentTimeMillis();

        // 把生成的验证码存储到redis服务中
        stringRedisTemplate.opsForValue().set(SMSConstant.SMS_CODE_PERFIX + phone, newCode, 5, TimeUnit.MINUTES);
        return R.ok();
    }

    @PostMapping("/sms/register")
    public String register(@Valid UserRegisterVO vo, BindingResult result, Model model) {
        // 校验参数
        Map<String, String> map = new HashMap<>();
        if (result.hasErrors()) {
            List<FieldError> fieldErrors = result.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                map.put(field, defaultMessage);
            }
            model.addAttribute("error", map);

            return "/reg";
        }

        // 验证码是否正确
        String s = stringRedisTemplate.opsForValue().get(SMSConstant.SMS_CODE_PERFIX + vo.getPhone(), 0, 100);
        s = s.split("_")[0];
        if (!s.equals(vo.getCode())) {
            map.put("code", "验证码错误");
            model.addAttribute("error", map);
            return "/reg";
        } else {
            // 验证码对了，需要清除缓存
            stringRedisTemplate.delete(SMSConstant.SMS_CODE_PERFIX + vo.getPhone());

            // 调用远程服务（会员），完成注册
            R register = memberFeignService.register(vo);
            if (register.getCode() == 0) {
                return "redirect:http://sxz.auth.com/login.html";
            }
            map.put("msg", register.getMsg());
            model.addAttribute("error", map);
            return "/reg";
        }
    }


    /**
     * 登录逻辑， 表单提交过来，参数是拼接的方式
     *
     * @return
     */
    @PostMapping("/login")
    public String login(LoginVO loginVO, RedirectAttributes redirectAttributes, HttpSession session) {
        R r = memberFeignService.login(loginVO);
        if (r.getCode() == 0) {


//            session.setAttribute("login", "bobo烤鸭");
            String jsonString = (String) r.get("entity");
            MemberVO memberVO = JSON.parseObject(jsonString, MemberVO.class);

            // 测试时候直接缓存到redis
            stringRedisTemplate.opsForValue().set(AuthConstant.AUTH_SESSION_REDIS, jsonString);

            session.setAttribute("loginUser", memberVO);
            return "redirect:http://sxz.mall.com/";
        } else {
//            Map<String, String> map = new HashMap<>();
//            map.put("msg", "账号或密码错误");
            redirectAttributes.addAttribute("errors", r.getMsg());
            return "redirect://http:sxz.auth.com/login.html";
        }

    }
}
